package mvc.config;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import mvc.annotation.Controller;
import mvc.annotation.RequestMapping;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ConfigFileReader {
	
	public ConfigFileReader(){
		
	}
	
	/**

	 * 通过配置文件和注解装载一个Map对象，并返回key值为请求的url

	 * @param path

	 * @return 根据扫描包集合获取的请求映射和类对应关系集合

	 */
	public static Map<String, String[]> loadConfig(String path){
		SAXReader reader = new SAXReader();
		Map<String, String[]> map = new HashMap<String, String[]>();
		try {
			Document doc = reader.read(new File(path));
			Element root = doc.getRootElement();
			
			map.putAll(getMapping(root));//扫描注解方式

		} catch (Exception e1) {
			// TODO Auto-generated catch block

			e1.printStackTrace();
		}
		return map;
	}
	
	/**

	 * 扫描包文件的类并转为换为请求映射集合

	 * @param root 配置文件根节点

	 * @return 扫描请求映射集合

	 */
	private static Map<String,String[]> getMapping(Element root){
		//获取所有包

		Element e = root.element("controller-scan");
		
		String[] packages = e.attributeValue("package").split(",");
		//获取包里所有类

		
		List<Class> classes = new ArrayList<Class>();
		String classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		for(String pack : packages){
			String fileurl = classpath+pack.replace(".","/");
			File file = new File(fileurl);
			File[] files = file.listFiles();
			for(File f : files){
				if(!f.isDirectory()){
					try {
						String fname = f.getName().substring(0, f.getName().lastIndexOf("."));
						classes.add(Class.forName(pack+"."+fname));
					} catch (ClassNotFoundException e1) {
						e1.printStackTrace();
					}
				}
			}
		}
		
		//解析类的注解

		Map<String,String[]> map= new HashMap<String, String[]>();
		for(Class clazz : classes){
			//Controller类名

			Controller cont = (Controller) clazz.getAnnotation(Controller.class);
			if(cont!=null){
				Method[] methods = clazz.getMethods();
				for(Method m : methods){
					//方法的ReqMapping注解

					RequestMapping req = m.getAnnotation(RequestMapping.class);
					if(req!=null){
						StringBuffer paraNames = new StringBuffer();
						for(Class para : m.getParameterTypes()){
							//方法的参数

							paraNames.append(","+para.getName());
						}
						String url = req.value();
						//装载map   

						//value值为对应的String数组 ｛Controller类，方法，方法参数｝  						

						String[] value = new String[3];	
						value[0] = clazz.getName();
						value[1] = m.getName();
						value[2] = paraNames.substring(1);
						map.put(url, value);
					}
				}
			}	
		}
		return map;
	}

	/**

	 * 把请求内容参数封装为bean

	 * @param clazz 要封装的类

	 * @param request 请求对象

	 * @return 封装好的bean信息

	 */
	public static Object getFormInfo(Class clazz,HttpServletRequest request){
		
		Object form = null;
		
		try{
			form = (Object)clazz.newInstance();
			Field[] fileds = clazz.getDeclaredFields();
			
			for(Field f:fileds){
				
				f.setAccessible(true);
				f.set(form, request.getParameter(f.getName()));
				f.setAccessible(false);
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return form;
	}
}
